﻿using FinalPointSet.View.Dialog;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;

namespace FinalPointSet.Model.Asset
{
    public static class AssetUtil
    {
        /// <summary>
        /// 返回绝对路径
        /// 例如: 传入 Assets\\Images\\logo.png
        /// </summary>
        /// <param name="path">相对路径</param>
        /// <returns>绝对路径</returns>
        public static string GetAbsolutePath(string path)
        {
            return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
        }

        /// <summary>
        /// 获取相对路径
        /// </summary>
        /// <param name="path">绝对路径</param>
        /// <returns></returns>
        public static string GetRelativePath(string path)
        {
            return path.Replace(AppDomain.CurrentDomain.BaseDirectory, string.Empty);
        }
        /// <summary>
        /// 加载资源文件为字符串
        /// 例如: 传入 Assets\\Images\\logo.png
        /// </summary>
        /// <param name="path">相对路径</param>
        /// <returns>资源文件字符串</returns>
        public static string LoadFileAsString(string path)
        {
            //转为绝对路径
            string absPath = GetAbsolutePath(path);
            string data = string.Empty;
            try
            {
                data = File.ReadAllText(absPath, Encoding.UTF8);
            }
            catch (Exception)
            {
                Debug.Print($"AssetUtil.Load异常,加载路径:{absPath}");
            }
            return data;
        }

        /// <summary>
        /// 加载资源文件为字符串
        /// 例如: 传入 Assets\\Images\\logo.png
        /// </summary>
        /// <param name="path">相对路径</param>
        /// <returns>资源文件字符串</returns>
        public static string LoadAbsolutePathFileAsString(string path)
        {
            string data = string.Empty;
            try
            {
                data = File.ReadAllText(path);
            }
            catch (Exception)
            {
                Debug.Print($"AssetUtil.Load异常,加载路径:{path}");
            }
            return data;
        }

        public static List<string> LoadDirectoryAsListString(string dir)
        {
            string[]? filePath = GetFilesPath(dir);
            List<string> strings = new();
            if (filePath == null)
            {
                Debug.Print("AssetUtil.LoadDirectoryAsListString(),加载文件失败");
                return new List<string>();
            }
            for (int i = 0; i < filePath.Length; i++)
            {
                strings.Add(LoadFileAsString(filePath[i]));
            }
            return strings;
        }

        /// <summary>
        /// 保存字符串为文件
        /// </summary>
        /// <param name="data">字符串数据</param>
        /// <param name="path">保存的文件路径(带后缀)</param>
        /// <exception cref="Exception"></exception>
        public static void SaveTextAsFile(string data, string path, JsonConverter? convert = null)
        {
            string absPath = GetAbsolutePath(path);
            try
            {
                File.WriteAllText(absPath, data);
            }
            catch (Exception e)
            {
                throw new Exception($"AssetUtil.SaveTextAsFile保存数据失败，失败原因：{e.Message}");
            }
        }

        /// <summary>
        /// 加载Json文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static T? LoadJsonAsObject<T>(string path, JsonConverter? convert = null)
        {
            //从磁盘加载文件
            string? srcData = LoadFileAsString(path);
            if (string.IsNullOrEmpty(srcData))
            {
                Debug.Print($"AssetUtil.Load<T>加载异常");
                return default;
            }
            //解析json数据
            try
            {
                T? data;
                if (convert == null)
                {
                    data = JsonConvert.DeserializeObject<T?>(srcData);
                }
                else
                {
                    data = JsonConvert.DeserializeObject<T?>(srcData, convert);
                }
                return data;
            }
            catch (Exception e)
            {
                throw new Exception($"AssetUtil.FromJson<T>解析，异常原因：{e.Message}");
            }
        }

        /// <summary>
        /// 加载json文件数据
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="path">文件路径</param>
        /// <returns>目标类型集合</returns>
        public static List<T>? LoadJsonAsObjects<T>(string path, JsonConverter? convert = null)
        {
            List<T>? datas;
            //从磁盘加载文件
            string? srcData = LoadFileAsString(path);
            if (string.IsNullOrEmpty(srcData))
            {
                Debug.Print($"AssetUtil.Load<T>加载异常");
                return null;
            }
            //解析json数据
            try
            {
                if (convert == null)
                {
                    datas = JsonConvert.DeserializeObject<List<T>?>(srcData);
                }
                else
                {
                    datas = JsonConvert.DeserializeObject<List<T>?>(srcData, convert);
                }
            }
            catch (Exception e)
            {
                throw new Exception($"AssetUtil.FromJson<T>解析，异常原因：{e.Message}");
            }

            return datas;
        }

        /// <summary>
        /// 保存对象为Json文件
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="datas">对象集合</param>
        /// <param name="path">保存Json文件的相对路径</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public static void SaveObjectsAsJson<T>(List<T> datas, string path, JsonConverter? convert = null)
        {
            if (datas == null)
            {
                throw new ArgumentNullException($"AssetUtil.ToJson<T>输入参数为空");
            }
            string result;
            if (convert == null)
            {
                result = JsonConvert.SerializeObject(datas);
            }
            else
            {
                result = JsonConvert.SerializeObject(datas, convert);
            }
            SaveTextAsFile(result, path);
            Debug.Print($"AssetUtil.ToJson<T>,保存{datas.Count}条数据成功");

        }

        /// <summary>
        /// 保存对象为Json文件
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="datas">对象集合</param>
        /// <param name="path">保存Json文件的相对路径</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public static void SaveObjectAsJson<T>(T data, string path, JsonConverter? convert = null)
        {
            if (data == null)
            {
                throw new ArgumentNullException($"AssetUtil.ToJson<T>输入参数为空");
            }
            string result;
            if (convert == null)
            {
                result = JsonConvert.SerializeObject(data);
            }
            else
            {
                result = JsonConvert.SerializeObject(data, convert);
            }
            SaveTextAsFile(result, path);
            Debug.Print($"AssetUtil.ToJson<T>,保存数据成功");
        }

        /// <summary>
        /// 加载xml文件
        /// </summary>
        /// <param name="path">文件相对路径</param>
        /// <returns>XmlReader文件</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static XmlReader FromXml(string path)
        {
            string absPath = GetAbsolutePath(path);
            try
            {
                return XmlReader.Create(absPath);
            }
            catch (Exception e)
            {
                throw new ArgumentNullException($"AssetUtil.FromXml方法，加载xml文件失败，失败原因：{e.Message}");
            }

        }

        /// <summary>
        /// 获取文件夹下所有文件的路径
        /// </summary>
        /// <param name="path">指定文件夹的路径</param>
        /// <returns>所有文件的路径</returns>
        public static string[]? GetFilesPath(string dir)
        {
            string absPath = GetAbsolutePath(dir);
            string[] files;
            try
            {
                files = Directory.GetFiles(absPath);
            }
            catch (Exception e)
            {
                files = Array.Empty<string>();
                Debug.Print($"AssetUtil.GetFilesPath(),文件不存在,路径:{absPath},异常信息:{e.Message}");
            }
            string[] fileNames = new string[files.Length];
            for (int i = 0; i < files.Length; i++)
            {
                fileNames[i] = files[i];
            }

            return fileNames;
        }


        /// <summary>
        /// 获取文件夹下所有文件的名称(不包含文件后缀)
        /// </summary>
        /// <param name="dir">文件夹路径</param>
        /// <returns></returns>
        public static string[] GetFilesName(string dir)
        {
            string[]? fileFullNames = GetFilesPath(dir);
            if (fileFullNames == null || fileFullNames.Length == 0)
            {
                Debug.Print("AssetUtil.GetFilesName(),获取文件名称失败");
                return Array.Empty<string>();
            }
            string[]? fileNames = new string[fileFullNames.Length];
            for (int i = 0; i < fileNames.Length; i++)
            {
                fileNames[i] = GetFileName(fileFullNames[i]);
            }
            return fileNames;
        }

        /// <summary>
        /// 获取文件名称
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns>文件名称</returns>
        public static string GetFileName(string path)
        {
            return Path.GetFileNameWithoutExtension(path);
        }


    }
}
